﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace OSM
{
	public class osmperm : Permutator
	{
		List<OSMWay> input;

		public List<OSMBorder> borders = new List<OSMBorder>();

		public osmperm(List<OSMWay> iway)
		{
			input = new List<OSMWay>(iway);
		}
		protected override void ApplyStep(PermutationStep istep)
		{
			osmstep st = istep as osmstep;
			if (st.rev)
			{
				if (borders.Last().Ways.Last() != st.subject)
					throw new Exception("Stack error");
				borders.Last().RemoveLast();
				if (borders.Last().Ways.Count == 0)
					borders.RemoveAt(borders.Count - 1);
				input.Add(st.subject);
			}
			else
			{
				if (st.startnew)
					borders.Add(new OSMBorder());
				borders.Last().AddWay(st.subject, st.dir);
				input.Remove(st.subject);
			}
		}
		public override List<PermutationStep> GetValidSteps(int depth)
		{
			List<PermutationStep> res = new List<PermutationStep>();
			for (int i = 0; i < (depth == 0 ? 1 : input.Count); i++)
			{
				if (borders.Count > 0)
				{
					if (borders.Last().LastNode.ID == input[i].FirstNode.ID)
						res.Add(new osmstep(input[i], false, false));
					if (borders.Last().LastNode.ID == input[i].LastNode.ID)
						res.Add(new osmstep(input[i], true, false));
				}
				if (borders.Count == 0 || borders.Last().IsClosed())
				{
					res.Add(new osmstep(input[i], false, true));
					res.Add(new osmstep(input[i], true, true));
				}
			}
			return res;
		}
		public override void ResetState()
		{
			borders.Clear();
		}
		protected override PermutationResult CheckTable(int CurrentDepth)
		{
			//if (StepStack.Count == 1)
			//	return PermutationResult.Passed;

			OSMBorder last = borders.Last();
			if (last.IsConsistent())
			{
				if (input.Count == 0)
					return PermutationResult.Finished;
				return PermutationResult.Passed;
			}
			return PermutationResult.Failed;
		}
		protected override bool ProcessResult()
		{
			return base.ProcessResult();
		}
	}
	public class osmstep : PermutationStep
	{
		public bool rev;
		public bool dir;
		public bool startnew;
		public OSMWay subject;
		public osmstep(OSMWay w, bool d, bool n, bool re = false)
		{
			rev = re;
			dir = d;
			startnew = n;
			subject = w;
		}
		public override PermutationStep Reverse()
		{
			return new osmstep(subject, dir, startnew, true);
		}
	}
}